package com.iwomy.secureplat.platform.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.iwomy.secureplat.admin.api.entity.SysDept;
import com.iwomy.secureplat.common.core.util.R;
import com.iwomy.secureplat.common.security.util.SecurityUtils;
import com.iwomy.secureplat.platform.dto.BasicExpensesDeviceDTO;
import com.iwomy.secureplat.platform.dto.BasicExpensesDviceConfigDTO;
import com.iwomy.secureplat.platform.dto.MyDeptRemainResult;
import com.iwomy.secureplat.platform.entity.*;
import com.iwomy.secureplat.platform.exception.PlatformException;
import com.iwomy.secureplat.platform.service.BasicConsumptionRecordService;
import com.iwomy.secureplat.platform.service.BasicDeviceService;
import com.iwomy.secureplat.platform.service.BasicExpensesDeptDetailService;
import com.iwomy.secureplat.platform.utils.DeptFillUtils;
import com.iwomy.secureplat.platform.utils.RemoteDeptUtils;
import com.iwomy.secureplat.platform.mapper.BasicExpensesDviceConfigMapper;
import com.iwomy.secureplat.platform.mapper.BasicInventoryListMapper;
import com.iwomy.secureplat.platform.service.BasicExpensesDviceConfigService;
import com.iwomy.secureplat.platform.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 资费管理-设备配置及赠送记录管理
 *
 * @author pig
 * @date 2023-11-24 16:01:21
 */
@Slf4j
@Service
public class BasicExpensesDviceConfigServiceImpl extends ServiceImpl<BasicExpensesDviceConfigMapper, BasicExpensesDviceConfigEntity> implements BasicExpensesDviceConfigService {

	@Autowired
	private RemoteDeptUtils remoteDeptUtils;

	@Autowired
	private BasicInventoryListMapper inventoryListMapper;

	@Autowired
	private BasicDeviceService basicDeviceService;

	@Autowired
	private BasicExpensesDeptDetailService expensesDeptDetail;

	@Autowired
	private BasicConsumptionRecordService basicConsumptionRecordService;

	private int smsRemainNum = 0;//短信剩余数量
	private int payingSmsRemainNum = 0;//代付最新短信总限制剩余数量
	private int payingSmsDayRemainNum = 0;//代付最新短信日限剩余数量
	private int payingSmsMonthRemainNum = 0;//代付最新短信月限剩余数量
	private int ttsRemainNum = 0;//语音剩余数量
	private int payingTtsRemainNum = 0;//代付最新语音总限制剩余数量
	private int payingTtsDayRemainNum = 0;//代付最新短信日限剩余数量
	private int payingTtsMonthRemainNum = 0;//代付最新短信月限剩余数量
	private int deliveryMethod;
	private LocalDateTime expirationDate;

	//设备资费界面查询
	@Override
	public Page<BasicInventoryListVO> getBasicInventoryListPage(Page page, BasicExpensesDeviceDTO basicExpensesDeviceDTO) {
		MPJLambdaWrapper<BasicInventoryListEntity> wrapper = new MPJLambdaWrapper<>();
		wrapper.selectAll(BasicInventoryListEntity.class);

		if (ObjectUtil.isNotEmpty(basicExpensesDeviceDTO.getDeviceTypeId())) {
			LambdaQueryWrapper<BasicDeviceEntity> deviceWrapper = new LambdaQueryWrapper<>();
			deviceWrapper.eq(BasicDeviceEntity::getDeviceTypeId, basicExpensesDeviceDTO.getDeviceTypeId());
			List<BasicDeviceEntity> devices = basicDeviceService.list(deviceWrapper);
			if (!devices.isEmpty()) {
				List<Long> deviceIds = devices.stream().map(BasicDeviceEntity::getId).collect(Collectors.toList());
				wrapper.in(BasicInventoryListEntity::getDeviceId, deviceIds);
			}
		}
		if (ObjectUtil.isNotEmpty(basicExpensesDeviceDTO.getDeviceModelId())) {
			LambdaQueryWrapper<BasicDeviceEntity> deviceWrapper = new LambdaQueryWrapper<>();
			deviceWrapper.in(BasicDeviceEntity::getDeviceModelId, basicExpensesDeviceDTO.getDeviceModelId());
			List<BasicDeviceEntity> devices = basicDeviceService.list(deviceWrapper);
			if (!devices.isEmpty()) {
				List<Long> deviceIds = devices.stream().map(BasicDeviceEntity::getId).collect(Collectors.toList());
				wrapper.in(BasicInventoryListEntity::getDeviceId, deviceIds);
			}
		}

		if (StrUtil.isNotEmpty(basicExpensesDeviceDTO.getImei())) {
			wrapper.like(BasicInventoryListEntity::getImei, basicExpensesDeviceDTO.getImei());
		}

		if (ObjectUtil.isNotEmpty(basicExpensesDeviceDTO.getDeptLimit())) {
			if (basicExpensesDeviceDTO.getDeptLimit() == 20) {
				wrapper.in(BasicInventoryListEntity::getTransferDeptId, basicExpensesDeviceDTO.getDeptId());
			} else {
				List<SysDept> deptList = (List<SysDept>) remoteDeptUtils.getChildrenList(basicExpensesDeviceDTO.getDeptId()).getData();
				List<Long> deptIds = new ArrayList<>();
				for (SysDept dept : deptList) {
					deptIds.add(dept.getDeptId());
				}
				if (deptIds != null) {
					wrapper.in(BasicInventoryListEntity::getTransferDeptId, deptIds);
				}
			}
		} else {
			if (ObjectUtil.isNotEmpty(basicExpensesDeviceDTO.getDeptId())) {
				wrapper.in(BasicInventoryListEntity::getTransferDeptId, basicExpensesDeviceDTO.getDeptId());
			}
		}
		//过期时间
		String platformExpireDateStr = basicExpensesDeviceDTO.getPlatformExpireDate();
		if (StringUtils.isNotEmpty(platformExpireDateStr)) {
			LocalDate date = LocalDate.parse(platformExpireDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
			LocalDateTime dateTime = date.atStartOfDay();
			wrapper.gt(BasicInventoryListEntity::getPlatformExpireDate, dateTime);
		}
		//只查我出库的设备
		wrapper.in(BasicInventoryListEntity::getDeptId, SecurityUtils.getUser().getDeptId());

		Page<BasicInventoryListVO> expensesDeviceConfig = inventoryListMapper.selectJoinPage(page, BasicInventoryListVO.class, wrapper);
		List<BasicInventoryListVO> entityList = expensesDeviceConfig.getRecords();

		entityList.forEach(expensesDevice -> {
			Long deviceId = expensesDevice.getDeviceId();
			List<BasicExpensesDviceConfigEntity> deviceDetails = byDeviceIdList(deviceId);
			selectTotal(deviceDetails);

			deviceDetails.forEach(record -> {
				if (deliveryMethod == 20) {
					expensesDevice.setDeliveryMethod(deliveryMethod);
					expensesDevice.setExpirationDate(expirationDate);
				} else {
					expensesDevice.setDeliveryMethod(record.getDeliveryMethod());
					expensesDevice.setExpirationDate(record.getExpirationDate());
				}

			});

			DeviceInventoryListVO basicDevice = basicDeviceService.getDeviceInventoryList(deviceId);
			if (basicDevice != null) {
				expensesDevice.setCustomerDeptName(basicDevice.getDeptName());
				expensesDevice.setDeviceType(basicDevice.getDeviceType());
				expensesDevice.setDeviceModelName(basicDevice.getDeviceModelName());
				expensesDevice.setImei(basicDevice.getImei());
				expensesDevice.setDeviceCreateTime(basicDevice.getCreateTime());
			} else {
				expensesDevice.setDeviceType(expensesDevice.getDeviceTypeName());
			}

			Long transferDeptId = expensesDevice.getTransferDeptId();
			if (expensesDevice.getCustomerDeptName() == null) {
				String deptName = remoteDeptUtils.getDeptName(transferDeptId);
				expensesDevice.setCustomerDeptName(deptName);
			}
			if (payingSmsRemainNum != 999999) {
				expensesDevice.setSmsRemainNum(smsRemainNum + payingSmsRemainNum);
			} else {
				expensesDevice.setSmsRemainNum(payingSmsRemainNum);
			}
			if (payingTtsRemainNum != 999999) {
				expensesDevice.setTtsRemainNum(ttsRemainNum + payingTtsRemainNum);
			} else {
				expensesDevice.setTtsRemainNum(payingTtsRemainNum);
			}
			expensesDevice.setDeviceEnableTime(expensesDevice.getCreateTime());
		});
		DeptFillUtils.fill(expensesDeviceConfig);
		return expensesDeviceConfig;
	}

	//根据设备id查询赠送记录
	@Override
	public List<BasicExpensesDviceConfigVO> getDeliveryList(Long deviceId) {
		LambdaQueryWrapper<BasicExpensesDviceConfigEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BasicExpensesDviceConfigEntity::getDeviceId, deviceId);

		List<BasicExpensesDviceConfigEntity> deviceDetails = this.getBaseMapper().selectList(wrapper);

		List<BasicExpensesDviceConfigVO> deviceDetailVOs = deviceDetails.stream().map(deviceDetail -> {
			BasicExpensesDviceConfigVO deviceDetailVO = new BasicExpensesDviceConfigVO();
			BeanUtils.copyProperties(deviceDetail, deviceDetailVO);
			DeviceInventoryListVO basicDevice = basicDeviceService.getDeviceInventoryList(deviceId);
			if (basicDevice != null) {
				deviceDetailVO.setDeviceType(basicDevice.getDeviceType());
				deviceDetailVO.setDeviceModelName(basicDevice.getDeviceModelName());
				deviceDetailVO.setImei(basicDevice.getImei());
			}
			Long deptId = deviceDetail.getGiveDeptId();
			if (deptId != null) {
				String deptName = remoteDeptUtils.getDeptName(deptId);
				deviceDetailVO.setGiveDeptName(deptName);
			}
			Long customerDeptId = deviceDetail.getDeptId();
			if (customerDeptId != null) {
				String deptName = remoteDeptUtils.getDeptName(customerDeptId);
				deviceDetailVO.setDeptName(deptName);
			}
			return deviceDetailVO;
		}).collect(Collectors.toList());

		return deviceDetailVOs;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R newlyAddedBatch(BasicExpensesDviceConfigDTO basicExpensesDviceConfigDTO) {
		List<BasicExpensesDviceConfigEntity> deviceDetails = byDeviceIdList(basicExpensesDviceConfigDTO.getDeviceId());
		selectTotal(deviceDetails);
		Long deviceId = basicExpensesDviceConfigDTO.getDeviceId();
		BasicDeviceVO basicDeviceVO = basicDeviceService.getByIds(deviceId);
		if (ObjectUtil.isEmpty(basicDeviceVO)) {
			return R.failed("该设备已被删除，不可配置");
		}
		Long deptId = basicDeviceVO.getDeptId();
		//配送
		if (basicExpensesDviceConfigDTO.getDeliveryMethod() == 10) {
			getDeliveryMethod10(basicExpensesDviceConfigDTO, deptId);
		} else {
			getDeliveryMethod20(basicExpensesDviceConfigDTO, deptId);
		}
		return R.ok();
	}

	//配送
	private void getDeliveryMethod10(BasicExpensesDviceConfigDTO expensesDviceConfigDTO, Long deptId) {
		Map<String, Object> data = remoteDeptUtils.getDept(SecurityUtils.getUser().getDeptId());
		String parentIdString = (String) data.getOrDefault("parentId", null);
		Long parentId = Long.parseLong(parentIdString);

		//不是租户时才判断余额足不足
		if (parentId != 0) {
			QuerySmsTtsCountVO querySmsTtsCount = expensesDeptDetail.queryDeptCount(SecurityUtils.getUser().getDeptId());
			if (querySmsTtsCount.getSmsRemainNum() < expensesDviceConfigDTO.getSmsAddNum() ||
					querySmsTtsCount.getTtsRemainNum() < expensesDviceConfigDTO.getTtsAddNum()) {
				throw new PlatformException("短信/语音/剩余量不足！");
			}
		}
		DeviceInventoryListVO basicDevice = basicDeviceService.getDeviceInventoryList(expensesDviceConfigDTO.getDeviceId());

		if (expensesDviceConfigDTO.getSmsAddNum() != null) {
			BasicExpensesDviceConfigEntity expensesDviceConfig = new BasicExpensesDviceConfigEntity();
			BeanUtils.copyProperties(expensesDviceConfigDTO, expensesDviceConfig);
			expensesDviceConfig.setDeliveryNum(expensesDviceConfigDTO.getSmsAddNum());
			expensesDviceConfig.setUseRemainNum(expensesDviceConfigDTO.getSmsAddNum());
			expensesDviceConfig.setDeptId(deptId);
			expensesDviceConfig.setRemainNum(smsRemainNum + expensesDviceConfigDTO.getSmsAddNum());
			expensesDviceConfig.setGiveDeptId(SecurityUtils.getUser().getDeptId());
			expensesDviceConfig.setDeliveryMethod(10);
			expensesDviceConfig.setType(10);
			expensesDviceConfig.setDeviceType(basicDevice.getDeviceType());
			expensesDviceConfig.setDeviceModelName(basicDevice.getDeviceModelName());
			expensesDviceConfig.setImei(basicDevice.getImei());
			this.save(expensesDviceConfig);
		}
		if (expensesDviceConfigDTO.getTtsAddNum() != null) {
			BasicExpensesDviceConfigEntity expensesDviceConfig = new BasicExpensesDviceConfigEntity();
			BeanUtils.copyProperties(expensesDviceConfigDTO, expensesDviceConfig);
			expensesDviceConfig.setDeliveryNum(expensesDviceConfigDTO.getTtsAddNum());
			expensesDviceConfig.setUseRemainNum(expensesDviceConfigDTO.getTtsAddNum());
			expensesDviceConfig.setRemainNum(ttsRemainNum + expensesDviceConfigDTO.getTtsAddNum());
			expensesDviceConfig.setDeptId(deptId);
			expensesDviceConfig.setGiveDeptId(SecurityUtils.getUser().getDeptId());
			expensesDviceConfig.setDeliveryMethod(10);
			expensesDviceConfig.setType(20);
			expensesDviceConfig.setDeviceType(basicDevice.getDeviceType());
			expensesDviceConfig.setDeviceModelName(basicDevice.getDeviceModelName());
			expensesDviceConfig.setImei(basicDevice.getImei());
			this.save(expensesDviceConfig);
		}
		//方式为配送时为本单位设备时不扣除余额，非本单位设备时扣除本单位的配置余额
		if (deptId != SecurityUtils.getUser().getDeptId()) {
			expensesDeptDetail.deptDeductSms(expensesDviceConfigDTO.getSmsAddNum(), SecurityUtils.getUser().getDeptId());
			expensesDeptDetail.deptDeductTts(expensesDviceConfigDTO.getTtsAddNum(), SecurityUtils.getUser().getDeptId());
		}
		saveConsumptionRecord10(expensesDviceConfigDTO, deptId);

	}

	//配送写进消费记录中
	private void saveConsumptionRecord10(BasicExpensesDviceConfigDTO expensesDviceConfig, Long deptId) {
		DeviceInventoryListVO basicDevice = basicDeviceService.getDeviceInventoryList(expensesDviceConfig.getDeviceId());
		//本单位分配给下级单位成功后写进短信语音消费记录中
		if (expensesDviceConfig.getSmsAddNum() != null) {
			BasicConsumptionRecordEntity basicConsumptionRecord = new BasicConsumptionRecordEntity();
			basicConsumptionRecord.setDeptId(SecurityUtils.getUser().getDeptId());
			basicConsumptionRecord.setUsedType(60);
			basicConsumptionRecord.setNotificationType(10);
			basicConsumptionRecord.setSmsNumber(expensesDviceConfig.getSmsAddNum());
			basicConsumptionRecord.setCustomerDeptId(deptId);
			basicConsumptionRecord.setDeviceId(expensesDviceConfig.getDeviceId());
			getDevice(basicConsumptionRecord, basicDevice);
			basicConsumptionRecordService.save(basicConsumptionRecord);

		}
		if (expensesDviceConfig.getTtsAddNum() != null) {
			BasicConsumptionRecordEntity basicConsumptionRecord = new BasicConsumptionRecordEntity();
			basicConsumptionRecord.setDeptId(SecurityUtils.getUser().getDeptId());
			basicConsumptionRecord.setUsedType(60);
			basicConsumptionRecord.setNotificationType(20);
			basicConsumptionRecord.setTtsNumber(expensesDviceConfig.getTtsAddNum());
			basicConsumptionRecord.setCustomerDeptId(deptId);
			basicConsumptionRecord.setDeviceId(expensesDviceConfig.getDeviceId());
			getDevice(basicConsumptionRecord, basicDevice);
			basicConsumptionRecordService.save(basicConsumptionRecord);
		}
	}

	//代付写进消费记录中
	private void saveConsumptionRecord20(BasicExpensesDviceConfigDTO expensesDviceConfig, Long deptId) {
		DeviceInventoryListVO basicDevice = basicDeviceService.getDeviceInventoryList(expensesDviceConfig.getDeviceId());
		//本单位分配给下级单位成功后写进短信语音消费记录中
		if (expensesDviceConfig.getSmsTotalLimit() != null) {
			BasicConsumptionRecordEntity basicConsumptionRecord = new BasicConsumptionRecordEntity();
			basicConsumptionRecord.setDeptId(SecurityUtils.getUser().getDeptId());
			basicConsumptionRecord.setUsedType(70);
			basicConsumptionRecord.setNotificationType(10);
			basicConsumptionRecord.setSmsNumber(expensesDviceConfig.getSmsTotalLimit());
			basicConsumptionRecord.setCustomerDeptId(deptId);
			basicConsumptionRecord.setDeviceId(expensesDviceConfig.getDeviceId());
			getDevice(basicConsumptionRecord, basicDevice);
			basicConsumptionRecordService.save(basicConsumptionRecord);
		}
		if (expensesDviceConfig.getTtsTotalLimit() != null) {
			BasicConsumptionRecordEntity basicConsumptionRecord = new BasicConsumptionRecordEntity();
			basicConsumptionRecord.setDeptId(SecurityUtils.getUser().getDeptId());
			basicConsumptionRecord.setUsedType(70);
			basicConsumptionRecord.setNotificationType(20);
			basicConsumptionRecord.setTtsNumber(expensesDviceConfig.getTtsTotalLimit());
			basicConsumptionRecord.setCustomerDeptId(deptId);
			basicConsumptionRecord.setDeviceId(expensesDviceConfig.getDeviceId());
			getDevice(basicConsumptionRecord, basicDevice);
			basicConsumptionRecordService.save(basicConsumptionRecord);
		}
	}

	//代付
	private void getDeliveryMethod20(BasicExpensesDviceConfigDTO basicExpensesDviceConfigDTO, Long deptId) {
		sms(basicExpensesDviceConfigDTO, smsRemainNum, deptId);
		tts(basicExpensesDviceConfigDTO, ttsRemainNum, deptId);
		saveConsumptionRecord20(basicExpensesDviceConfigDTO, deptId);
	}

	//短信代付
	private void sms(BasicExpensesDviceConfigDTO basicExpensesDviceConfigDTO, int smsRemainNum, Long deptId) {
		BasicExpensesDviceConfigEntity expensesDviceConfig = new BasicExpensesDviceConfigEntity();
		BeanUtils.copyProperties(basicExpensesDviceConfigDTO, expensesDviceConfig);
		if (basicExpensesDviceConfigDTO.getSmsTotalLimit() == 999999) {
			expensesDviceConfig.setRemainNum(basicExpensesDviceConfigDTO.getSmsTotalLimit());
		} else {
			expensesDviceConfig.setRemainNum(smsRemainNum + basicExpensesDviceConfigDTO.getSmsTotalLimit());
		}
		expensesDviceConfig.setDeliveryMethod(20);
		expensesDviceConfig.setType(10);
		expensesDviceConfig.setDeliveryNum(basicExpensesDviceConfigDTO.getSmsTotalLimit());
		expensesDviceConfig.setUseRemainNum(basicExpensesDviceConfigDTO.getSmsTotalLimit());
		expensesDviceConfig.setTotalLimit(basicExpensesDviceConfigDTO.getSmsTotalLimit());
		expensesDviceConfig.setTotalLimitRemain(basicExpensesDviceConfigDTO.getSmsTotalLimit());
		expensesDviceConfig.setSumDay(basicExpensesDviceConfigDTO.getSmsSumDay());
		expensesDviceConfig.setSumDayRemain(basicExpensesDviceConfigDTO.getSmsSumDay());
		expensesDviceConfig.setSumMonth(basicExpensesDviceConfigDTO.getSmsSumMonth());
		expensesDviceConfig.setSumMonthRemain(basicExpensesDviceConfigDTO.getSmsSumMonth());
		expensesDviceConfig.setExpirationDate(basicExpensesDviceConfigDTO.getExpirationDate());
		expensesDviceConfig.setGiveDeptId(SecurityUtils.getUser().getDeptId());
		expensesDviceConfig.setDeptId(deptId);
		this.save(expensesDviceConfig);
	}

	//语音代付
	private void tts(BasicExpensesDviceConfigDTO basicExpensesDviceConfigDTO, int ttsRemainNum, Long deptId) {
		BasicExpensesDviceConfigEntity expensesDviceConfig = new BasicExpensesDviceConfigEntity();
		BeanUtils.copyProperties(basicExpensesDviceConfigDTO, expensesDviceConfig);
		if (basicExpensesDviceConfigDTO.getTtsTotalLimit() == 999999) {
			expensesDviceConfig.setRemainNum(basicExpensesDviceConfigDTO.getTtsTotalLimit());
		} else {
			expensesDviceConfig.setRemainNum(ttsRemainNum + basicExpensesDviceConfigDTO.getTtsTotalLimit());
		}
		expensesDviceConfig.setDeliveryMethod(20);
		expensesDviceConfig.setType(20);
		expensesDviceConfig.setDeliveryNum(basicExpensesDviceConfigDTO.getTtsTotalLimit());
		expensesDviceConfig.setUseRemainNum(basicExpensesDviceConfigDTO.getTtsTotalLimit());
		expensesDviceConfig.setTotalLimit(basicExpensesDviceConfigDTO.getTtsTotalLimit());
		expensesDviceConfig.setTotalLimitRemain(basicExpensesDviceConfigDTO.getTtsTotalLimit());
		expensesDviceConfig.setSumDay(basicExpensesDviceConfigDTO.getTtsSumDay());
		expensesDviceConfig.setSumDayRemain(basicExpensesDviceConfigDTO.getTtsSumDay());
		expensesDviceConfig.setSumMonth(basicExpensesDviceConfigDTO.getTtsSumMonth());
		expensesDviceConfig.setSumMonthRemain(basicExpensesDviceConfigDTO.getTtsSumMonth());
		expensesDviceConfig.setExpirationDate(basicExpensesDviceConfigDTO.getExpirationDate());
		expensesDviceConfig.setGiveDeptId(SecurityUtils.getUser().getDeptId());
		expensesDviceConfig.setDeptId(deptId);
		this.save(expensesDviceConfig);

	}


	//根据设备id查询所有记录
	private List<BasicExpensesDviceConfigEntity> byDeviceIdList(Long deviceId) {
		LambdaQueryWrapper<BasicExpensesDviceConfigEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BasicExpensesDviceConfigEntity::getDeviceId, deviceId);

		List<BasicExpensesDviceConfigEntity> deptDetails = this.getBaseMapper().selectList(wrapper);
		return deptDetails;
	}

	//查询短信语音剩余数(类型为配送的)
	private void selectTotal(List<BasicExpensesDviceConfigEntity> deptDetails) {
		smsRemainNum = 0;
		ttsRemainNum = 0;
		payingSmsRemainNum = 0;
		payingSmsDayRemainNum = 0;
		payingSmsMonthRemainNum = 0;
		payingTtsRemainNum = 0;
		payingTtsDayRemainNum = 0;
		payingTtsMonthRemainNum = 0;
		deliveryMethod = 0;
		smsRemainNum = deptDetails.stream()
				.filter(record -> record.getDeliveryMethod() == 10 && record.getType() == 10)
				.mapToInt(BasicExpensesDviceConfigEntity::getUseRemainNum)
				.sum();
		log.info("短信剩余量smsRemainNum:{}" + smsRemainNum);

		ttsRemainNum = deptDetails.stream()
				.filter(record -> record.getDeliveryMethod() == 10 && record.getType() == 20)
				.mapToInt(BasicExpensesDviceConfigEntity::getUseRemainNum)
				.sum();
		log.info("语音剩余量ttsRemainNum:{}" + ttsRemainNum);

		//短信语音代付的最新一条记录
		smsPayingLastRecord(deptDetails);
		ttsPayingLastRecord(deptDetails);
	}

	@Override
	public BasicExpensesDviceConfigVO selectDeviceRemain(List<BasicExpensesDviceConfigEntity> deptDetails) {
		selectTotal(deptDetails);
		BasicExpensesDviceConfigVO expensesDviceConfigVO = new BasicExpensesDviceConfigVO();
		expensesDviceConfigVO.setSmsRemainNum(smsRemainNum);
		expensesDviceConfigVO.setTtsRemainNum(ttsRemainNum);
		return expensesDviceConfigVO;
	}

	//短信代付的最后一条记录(类型为代付的)
	private Optional<BasicExpensesDviceConfigEntity> smsPayingLastRecord(List<BasicExpensesDviceConfigEntity> deptDetails) {
		LocalDateTime currentDateTime = LocalDateTime.now(); // 获取当前日期和时间
		//获取代付最新一条数据
		Optional<BasicExpensesDviceConfigEntity> latestRecord = deptDetails.stream()
				.filter(record -> record.getDeliveryMethod() == 20 && record.getType() == 10)
				.sorted(Comparator.comparing(BasicExpensesDviceConfigEntity::getCreateTime).reversed()) // 按照 CreateTime 降序排序
				.findFirst(); // 获取第一条记录

		if (latestRecord.isPresent()) {
			BasicExpensesDviceConfigEntity record = latestRecord.get();
			// 判断短信代付时间是否到期
			if (record.getExpirationDate() != null && currentDateTime.isBefore(record.getExpirationDate())) {
				payingSmsRemainNum = record.getUseRemainNum();
				payingSmsDayRemainNum = record.getSumDayRemain();
				payingSmsMonthRemainNum = record.getSumMonthRemain();
				deliveryMethod = record.getDeliveryMethod();
				expirationDate = record.getExpirationDate();
			}
		}
		return latestRecord;
	}

	//语音代付的最后一条记录(类型为代付的)
	private Optional<BasicExpensesDviceConfigEntity> ttsPayingLastRecord(List<BasicExpensesDviceConfigEntity> deptDetails) {
		LocalDateTime currentDateTime = LocalDateTime.now(); // 获取当前日期和时间
		//获取代付最新一条数据
		Optional<BasicExpensesDviceConfigEntity> latestRecord = deptDetails.stream()
				.filter(record -> record.getDeliveryMethod() == 20 && record.getType() == 20)
				.sorted(Comparator.comparing(BasicExpensesDviceConfigEntity::getCreateTime).reversed()) // 按照 CreateTime 降序排序
				.findFirst(); // 获取第一条记录

		if (latestRecord.isPresent()) {
			BasicExpensesDviceConfigEntity record = latestRecord.get();
			// 判断短信代付时间是否到期
			if (record.getExpirationDate() != null && currentDateTime.isBefore(record.getExpirationDate())) {
				payingTtsRemainNum = record.getUseRemainNum();
				payingTtsDayRemainNum = record.getSumDayRemain();
				payingTtsMonthRemainNum = record.getSumMonthRemain();
				deliveryMethod = record.getDeliveryMethod();
				expirationDate = record.getExpirationDate();
			}
		}
		return latestRecord;
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean sendSmsOrTts(BasicDeviceEntity device, int sendType) {
		log.info("sendSmsOrTts:{}",JSONObject.toJSONString(device));
		try {
			Long parentId = remoteDeptUtils.getParentId(device.getDeptId());
			//不是租户时才判断余额足不足
			if (parentId.equals(0L))
				return true;
			MyDeptRemainResult deptRemain = myDeptRemain(device);
			int deviceSmsRemain = deptRemain.getDeviceSmsRemain();
			int myDeptSmsRemain = deptRemain.getMyDeptSmsRemain();
			int deviceTtsRemain = deptRemain.getDeviceTtsRemain();
			int myDeptTtsRemain = deptRemain.getMyDeptTtsRemain();

			if (sendType == 10 && (deviceSmsRemain + myDeptSmsRemain) > 0) {
				log.info("可以扣除短信类型10短信20语音: {}", sendType);
				return true;
			}
			if (sendType == 20 && (deviceTtsRemain + myDeptTtsRemain) > 0) {
				log.info("扣除短信类型10短信20语音: {}", sendType);
				return true;
			}
			log.info("短信余额不足: {}", sendType);
			return false; // 其他情况返回 false
		} catch (Exception e) {
			log.error("发送短信或语音时发生异常: {}", e.getMessage());
			e.printStackTrace();
			return false; // 发送短信/语音失败，返回 false
		}
	}


	private MyDeptRemainResult myDeptRemain(BasicDeviceEntity device) {
		MyDeptRemainResult myDeptRemainResult = new MyDeptRemainResult();

		// 先查询设备的配送记录
		LambdaQueryWrapper<BasicExpensesDviceConfigEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.in(BasicExpensesDviceConfigEntity::getDeviceId, device.getId());

		List<BasicExpensesDviceConfigEntity> expensesDeviceDetail = this.getBaseMapper().selectList(wrapper);
		selectTotal(expensesDeviceDetail);

		//查询本单位的余额
		QuerySmsTtsCountVO querySmsTtsCount = expensesDeptDetail.queryDeptCount(device.getDeptId());
		int myDeptSmsRemain = querySmsTtsCount.getSmsRemainNum();
		int myDeptTtsRemain = querySmsTtsCount.getTtsRemainNum();

		myDeptRemainResult.setDeviceSmsRemain(smsRemainNum);
		myDeptRemainResult.setDeviceTtsRemain(ttsRemainNum);
		myDeptRemainResult.setMyDeptSmsRemain(myDeptSmsRemain);
		myDeptRemainResult.setMyDeptTtsRemain(myDeptTtsRemain);
		return myDeptRemainResult;
	}

	/**
	 * 短信扣费
	 *
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deviceDeductSms(Long deviceId, int smsAddNum, Long deptId, BasicNotificationRecordEntity basicNotificationRecordEntity) {
		BasicDeviceEntity device = new BasicDeviceEntity();
		device.setId(deviceId);
		device.setDeptId(deptId);
		MyDeptRemainResult deptRemain = myDeptRemain(device);
		int deviceSmsRemain = deptRemain.getDeviceSmsRemain();
		log.info("设备短信剩余:{}" + deviceSmsRemain);
		if (deviceSmsRemain != 0) {
			//扣除自己
			addConsumptionRecord(deviceId, smsAddNum, deptId, 10, 30, basicNotificationRecordEntity);
			return deviceSms(deviceId, smsAddNum, deptId);
		} else {
			//扣除单位
			addConsumptionRecord(deviceId, smsAddNum, deptId, 10, 20, basicNotificationRecordEntity);
			Map<String, Object> data = remoteDeptUtils.getExpenses(deptId);
			String parentIdString = (String) data.getOrDefault("parentId", null);
			Long parentId = Long.parseLong(parentIdString);
			//设备所属单位不是租户时，扣除对应单位的资费
			if (!parentId.equals(0L)) {
				return expensesDeptDetail.deptDeductSms(smsAddNum, deptId);
			}
			return true;
		}
	}

	/**
	 * 语音扣费
	 *
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deviceDeductTts(Long deviceId, int ttsAddNum, Long deptId, BasicNotificationRecordEntity basicNotificationRecordEntity) {
		BasicDeviceEntity device = new BasicDeviceEntity();
		device.setId(deviceId);
		device.setDeptId(deptId);
		MyDeptRemainResult deptRemain = myDeptRemain(device);
		int deviceTtsRemain = deptRemain.getDeviceTtsRemain();
		log.info("设备语音剩余:{}" + deviceTtsRemain);
		if (deviceTtsRemain != 0) {
			//扣除自己
			addConsumptionRecord(deviceId, ttsAddNum, deptId, 20, 30, basicNotificationRecordEntity);
			return deviceTts(deviceId, ttsAddNum, deptId);
		} else {
			//扣除单位
			addConsumptionRecord(deviceId, ttsAddNum, deptId, 20, 20, basicNotificationRecordEntity);
			Map<String, Object> data = remoteDeptUtils.getExpenses(deptId);
			String parentIdString = (String) data.getOrDefault("parentId", null);
			Long parentId = Long.parseLong(parentIdString);
			//设备所属单位不是租户时，扣除对应单位的资费
			if (!parentId.equals(0L)) {
				return expensesDeptDetail.deptDeductTts(ttsAddNum, deptId);
			}
			return true;
		}
	}

	//设备短信数扣除
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deviceSms(Long deviceId, int smsAddNum, Long deptId) {
		// 先查询本设备的记录
		LambdaQueryWrapper<BasicExpensesDviceConfigEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.in(BasicExpensesDviceConfigEntity::getDeviceId, deviceId);

		List<BasicExpensesDviceConfigEntity> expensesDeptDetail = this.getBaseMapper().selectList(wrapper);
		//配送的列表
		List<BasicExpensesDviceConfigEntity> smsRecord = expensesDeptDetail.stream()
				.sorted(Comparator.comparing(BasicExpensesDviceConfigEntity::getCreateTime))
				.filter(record -> record.getDeliveryMethod() == 10 && record.getUseRemainNum() > 0 && record.getType() == 10)
				.collect(Collectors.toList());

		boolean success = false;
		// 按时间顺序扣除设备
		for (BasicExpensesDviceConfigEntity record : smsRecord) {
			int toDeduct = Math.min(record.getUseRemainNum(), smsAddNum);
			record.setUseRemainNum(record.getUseRemainNum() - toDeduct);
			success = this.updateById(record);
			if (!success) {
				break;
			}
			smsAddNum -= toDeduct;
			if (smsAddNum <= 0) {// 如果没有剩余的设备需要扣除，则跳出循环
				success = true;
				break;
			}
		}
		log.info("设备短信扣除结果:{}" + success);
		return success;
	}

	//设备语音数扣除
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deviceTts(Long deviceId, int ttsAddNum, Long deptId) {
		// 先查询本设备的记录
		LambdaQueryWrapper<BasicExpensesDviceConfigEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.in(BasicExpensesDviceConfigEntity::getDeviceId, deviceId);

		List<BasicExpensesDviceConfigEntity> expensesDeptDetail = this.getBaseMapper().selectList(wrapper);
		//配送的列表
		List<BasicExpensesDviceConfigEntity> ttsRecord = expensesDeptDetail.stream()
				.sorted(Comparator.comparing(BasicExpensesDviceConfigEntity::getCreateTime))
				.filter(record -> record.getDeliveryMethod() == 10 && record.getUseRemainNum() > 0 && record.getType() == 20)
				.collect(Collectors.toList());

		boolean success = false;
		// 按时间顺序扣除设备
		for (BasicExpensesDviceConfigEntity record : ttsRecord) {
			int toDeduct = Math.min(record.getUseRemainNum(), ttsAddNum);
			record.setUseRemainNum(record.getUseRemainNum() - toDeduct);
			success = this.updateById(record);
			if (!success) {
				break;
			}
			ttsAddNum -= toDeduct;
			if (ttsAddNum <= 0) {// 如果没有剩余的设备需要扣除，则跳出循环
				success = true;
				break;
			}
		}
		log.info("设备语音扣除结果:{}" + success);
		return success;
	}

	//出库配送记录到消费记录表
	private void addConsumptionRecord(Long deviceId, int addNum, Long deptId, int notificationType, int cnsumeType, BasicNotificationRecordEntity basicNotificationRecordEntity) {
		DeviceInventoryListVO basicDevice = basicDeviceService.getDeviceInventoryList(deviceId);
		BasicConsumptionRecordEntity basicConsumptionRecord = new BasicConsumptionRecordEntity();
		basicConsumptionRecord.setDeptId(deptId);
		basicConsumptionRecord.setDeviceId(deviceId);
		basicConsumptionRecord.setUsedType(50);
		basicConsumptionRecord.setNotificationType(notificationType);
		basicConsumptionRecord.setConsumeType(cnsumeType);
		basicConsumptionRecord.setCustomerDeptId(deptId);
		basicConsumptionRecord.setReceiver(basicNotificationRecordEntity.getReceiverName());
		basicConsumptionRecord.setReceivePhone(basicNotificationRecordEntity.getReceiverId());
		if (notificationType == 10) {
			basicConsumptionRecord.setSmsNumber(addNum);
		}
		if (notificationType == 20) {
			basicConsumptionRecord.setTtsNumber(addNum);
		}
		getDevice(basicConsumptionRecord, basicDevice);
//		basicConsumptionRecord.setTenantId(SecurityUtils.getUser().getTenantId());
		basicConsumptionRecordService.save(basicConsumptionRecord);
	}

	private BasicConsumptionRecordEntity getDevice(BasicConsumptionRecordEntity consumptionRecord, DeviceInventoryListVO basicDevice) {
		consumptionRecord.setDeviceType(basicDevice.getDeviceType());
		consumptionRecord.setDeviceModelName(basicDevice.getDeviceModelName());
		consumptionRecord.setImei(basicDevice.getImei());
		return consumptionRecord;
	}
}